<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Bloblang Editor</title>
    <style>
        html, body {
            background-color: #202020;
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
        }

        .panel {
            position: absolute;
            margin: 0;
        }

        .panel > h2 {
            position: absolute;
            text-align: center;
            width: 100px;
            background-color: #33352e;
            color: white;
            font-family: monospace;
            border-bottom: solid #a6e22e 2px;
        }

        #input, #output, #mapping {
            background-color: #33352e;
            height: 100%;
            width: 100%;
            overflow: auto;
            box-sizing: border-box;
            margin: 0;
            padding: 10px;
            font-size: 12pt;
            font-family: monospace;
            color: #fff;
            border: solid #33352e 2px;
        }

        #ace-mapping, #ace-input {
            font-size: 14pt;
            overflow: auto;
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
            border: solid #33352e 2px;
        }

        textarea {
            resize: none;
        }
    </style>
</head>
<body>
<div class="panel" id="default-input-panel" style="top:0;bottom:50%;left:0;right:50%;padding:0 5px 5px 0">
    <h2 style="left:50%;bottom:0;margin-left:-50px;">Input</h2>
    <textarea id="input">{{.InitialInput}}</textarea>
</div>
<div class="panel" id="ace-input-panel" style="top:0;bottom:50%;left:0;right:50%;padding:0 5px 5px 0;display:none">
    <h2 style="left:50%;bottom:0;margin-left:-50px;z-index:100;background-color:#272822;">Input</h2>
    <div id="ace-input"></div>
</div>
<div class="panel" style="top:0;bottom:50%;left:50%;right:0;padding:0 0 5px 5px">
    <h2 style="left:50%;bottom:0;margin-left:-50px;">Output</h2>
    <pre id="output"></pre>
</div>
<div class="panel" id="default-mapping-panel" style="top:50%;bottom:0;left:0;right:0;padding: 5px 0 0 0">
    <h2 style="left:50%;bottom:0;margin-left:-50px;">Mapping</h2>
    <textarea id="mapping">{{.InitialMapping}}</textarea>
</div>
<div class="panel" id="ace-mapping-panel" style="top:50%;bottom:0;left:0;right:0;padding: 5px 0 0 0;display:none">
    <h2 style="left:50%;bottom:0;margin-left:-50px;z-index:100;background-color:#272822;">Mapping</h2>
    <div id="ace-mapping"></div>
</div>
</body>
<script>
    function execute() {
        const request = new Request('execute', {
            method: 'POST',
            body: JSON.stringify({
                mapping: getMapping(),
                input: getInput(),
            }),
        });
        fetch(request)
            .then(response => {
                if (response.status === 200) {
                    return response.json();
                } else {
                    throw new Error('Something went wrong on api server!');
                }
            })
            .then(response => {
                const red = "#f92672";
                let result = "No result";
                inputArea.style.borderColor = "#33352e";
                mappingArea.style.borderColor = "#33352e";
                outputArea.style.color = "white";
                if (response.result.length > 0) {
                    result = document.createTextNode(response.result);
                } else if (response.mapping_error.length > 0) {
                    inputArea.style.borderColor = red;
                    outputArea.style.color = red;
                    result = document.createTextNode(response.mapping_error);
                } else if (response.parse_error.length > 0) {
                    mappingArea.style.borderColor = red;
                    outputArea.style.color = red;
                    result = document.createTextNode(response.parse_error);
                }
                outputArea.innerHTML = "";
                outputArea.appendChild(result);
            }).catch(error => {
            console.error(error);
        });
    }

    var mappingArea = document.getElementById("mapping");
    var aceMappingEditor = null;

    function getMapping() {
        if (aceMappingEditor !== null) {
            return aceMappingEditor.getValue();
        }
        return mappingArea.value;
    }

    var inputArea = document.getElementById("input");
    var aceInputEditor = null;

    function getInput() {
        if (aceInputEditor !== null) {
            return aceInputEditor.getValue();
        }
        return inputArea.value;
    }

    const outputArea = document.getElementById("output");
    const inputs = document.getElementsByTagName('textarea');
    for (let input of inputs) {
        input.addEventListener('keydown', function (e) {
            if (e.key == 'Tab') {
                e.preventDefault();
                var start = this.selectionStart;
                var end = this.selectionEnd;

                // set textarea value to: text before caret + tab + text after caret
                this.value = this.value.substring(0, start) +
                    "    " + this.value.substring(end);

                // put caret at right position again
                this.selectionStart = start + 4;
                this.selectionEnd = end + 4;
            }
        });
        input.addEventListener('input', function (e) {
            execute();
        })
    }
    execute();
</script>

<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.15.0/src-min-noconflict/ace.js"
    integrity="sha256-LDAbbBwaA1DWzagfX4uwqj9iddOjEYwTiV1xQeKVdEg=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.15.0/src-min-noconflict/theme-monokai.js"
    integrity="sha256-eBZhzA3IYQvEVQnnT67zSIZegWYQdXDJoLr6IAOXY4M=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.15.0/src-min-noconflict/mode-coffee.js"
    integrity="sha256-KfNo+n6fdx9+bT4hbsyp+2n4XDp8gRIqYFdDjVRHlNQ=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.15.0/src-min-noconflict/mode-json.js"
    integrity="sha256-NRrS1x8Lu3yntlnkoj1sViPUV/Tyahtm7i1g4llyRYQ=" crossorigin="anonymous"></script>
<script>
    currentMapping = getMapping();
    aceMappingEditor = ace.edit("ace-mapping");
    aceMappingEditor.setValue(currentMapping, 1);
    aceMappingEditor.session.setMode("ace/mode/coffee");
    mappingArea = document.getElementById("ace-mapping");

    document.getElementById("default-mapping-panel").style.display = "none";
    document.getElementById("ace-mapping-panel").style.display = "initial";

    currentInput = getInput();
    aceInputEditor = ace.edit("ace-input");
    aceInputEditor.setValue(currentInput, 1);
    aceInputEditor.session.setMode("ace/mode/json");
    inputArea = document.getElementById("ace-input");

    document.getElementById("default-input-panel").style.display = "none";
    document.getElementById("ace-input-panel").style.display = "initial";

    [aceMappingEditor, aceInputEditor].forEach(function (editor) {
        editor.on('change', execute);
        editor.setTheme("ace/theme/monokai");
        editor.session.setTabSize(4);
        editor.session.setUseSoftTabs(true);
        editor.session.setUseWorker(false);
    });
</script>
</html>